﻿using Microsoft.AspNetCore.Mvc;
using System;
using ZhCun.DBModel;
using ZhCun.Utils;
using ZhCun.Utils.Helpers;
using ZhCun.WebUtils;
using ZhCun.WebUtils.Authorizes;
using ZhCun.WebUtils.Configs;
using ZhCun.WebUtils.DB;

namespace ZhCun.WebUtils
{
    public class BaseApiUserController<TUserBLL> : BaseApiController<TUserBLL>
        where TUserBLL : UserBaseBLL, new()
    { }

    public class BaseApiUserController : BaseApiController<UserBaseBLL>
    {
        const string IMG_CODE_KEY = "{ACC9D599-6D09-4B4A-B837-5A6B5E541A1A}";

        [NonAction]
        protected ApiResult Login(UserLoginArg arg, int loginType)
        {
            if (arg.LoginName.IsEmpty())
            {
                return BLLObj.RetErr("用户名不能为空");
            }

            if (arg.LoginName.IsEmpty())
            {
                return BLLObj.RetErr("密码不能为空");
            }
            if (loginType == 0)
            {
                var imgCode = HttpContext.GetSession(IMG_CODE_KEY, true);
                if (!arg.VerifyCode.StringEquals(imgCode))
                {
                    return BLLObj.RetErr("验证码错误");
                }
            }
            var r = BLLObj.Login(arg);
            if (!r) return r;

            LoginUser user = new LoginUser
            {
                UserId = r.data.Id,
                RoleId = r.data.RoleId,
                UserName = r.data.UserName,
            };

            int expiresMin = loginType == 1 ? CommonConfig.THIS.TokenTimeOutApi : CommonConfig.THIS.TokenTimeOutPage;
            user.Expires = TimeSpan.FromMinutes(expiresMin);
            string token = LoginState.Set(user);
            if (loginType == 1)
            {
                return BLLObj.RetOK(new UserLoginRet
                {
                    Token = token,
                    UserName = user.UserName,
                    ExpiresTime = user.ExpiresTime
                });
            }
            else
            {
                HttpContext.SetCookieToken(token, user.ExpiresTime);
                return BLLObj.RetOK("登陆成功");
            }
        }

        /// <summary>
        /// api登录
        /// </summary>
        [UserAuthorize(false)]
        [Route("/api/login")]
        [HttpPost]
        [BodyEncryptFilter]
        public ApiResult LoginApi(UserLoginArg arg)
        {
            return Login(arg, 1);
        }

        /// <summary>
        /// api登录
        /// </summary>
        [UserAuthorize(false)]
        [Route("/page/login")]
        [BodyEncryptFilter]
        [HttpPost]
        [SwaggerHidden]
        public ApiResult LoginPage(UserLoginArg arg)
        {
            return Login(arg, 0);
        }

        /// <summary>
        /// 获取登录验证码
        /// </summary>
        [HttpGet]
        [UserAuthorize(false)]
        public IActionResult GetLoginVerifyCode()
        {
            var img = ImageHelper.GetVerifyCodeToBytes(130, 39, 5, out string code);
            HttpContext.SetSession(IMG_CODE_KEY, code);
            return File(img, @"image/jpeg");
        }
        /// <summary>
        /// token登录，重新登录时通过token，失败时请使用用户名登录，ClientSN不一致验证不通过
        /// </summary>        
        [HttpPost]
        public ApiResult LoginToken()
        {
            UserLoginRet ret = new UserLoginRet();
            ret.Token = LoginState.CreateToken(CurrUser);
            ret.UserName = CurrUser.UserName;
            ret.ExpiresTime = CurrUser.ExpiresTime;
            return BLLObj.RetOK(ret);
        }
        /// <summary>
        /// 保存用户信息
        /// </summary>
        [HttpPost]
        public ApiResult InfoSave(Sys_User m)
        {
            var r = BLLObj.SaveInfo(m);
            return r;
        }
        /// <summary>
        /// 修改密码保存
        /// </summary>
        [HttpPost]
        public ApiResult ChangePwd(User_ChangePwd arg)
        {
            return BLLObj.ChangePwd(arg);
        }
        /// <summary>
        /// 用户登录退出
        /// </summary>
        [HttpPost]
        public ApiResult LoginOut()
        {
            var token = HttpContext.GetToken();
            LoginState.Remove(token);
            HttpContext.DelCookieToken();
            return BLLObj.LoginOut();
        }
    }
}